﻿#region Using statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Rectangular.Model.Interfaces;
#endregion

namespace Rectangular.Model.Entities
{
    public abstract class Sprite : ICollidable
    {
        #region Members
        /* The texture of the sprite */
        public static Texture2D Texture;
        
        /* A randomizer */
        protected static Random _random;

        /* The color of the sprite */
        private Color _color;
        
        /* The position of the sprite */
        private Vector2 _position;

        /* The destination of the sprite */
        private Vector2 _destination;

        /* The velocity of the sprite */
        private Vector2 _velocity;

        /* The moving speed of the sprite */
        private float _movingSpeed;

        /* The rotation of the sprite */
        private float _rotation;

        /* The height of the sprite */
        private int _height;

        /* The width of the sprite */
        private int _width;

        /* Is the sprite visible */
        private bool _visible;
        #endregion

        #region Constructors
        /// <summary>
        /// Constructs a new sprite
        /// </summary>
        public Sprite()
        {
            _random = new Random();
            MovingSpeed = 5;
            Visible = true;
        }
        #endregion

        #region Properties
        /// <summary>
        /// The color of the sprite
        /// </summary>
        public Color Color {
            get { return _color; }
            set { _color = value; }
        }

        /// <summary>
        /// The position of the sprite
        /// </summary>
        public Vector2 Position
        {
            get { return _position; }
            set { _position = value; }
        }

        /// <summary>
        /// The destination of the sprite
        /// </summary>
        public Vector2 Destination
        {
            get { return _destination; }
            set
            {
                _destination = value;
                _velocity = (Destination - Position);
                _velocity = Vector2.Normalize(_velocity);
            }
        }

        /// <summary>
        /// The height of the sprite
        /// </summary>
        public int Height { get; set; }

        /// <summary>
        /// The width of the sprite
        /// </summary>
        public int Width { get; set; }

        /// <summary>
        /// The rotation of the sprite
        /// </summary>
        public float Rotation
        {
            get { return _rotation; }
            set { _rotation = value; }
        }

        /// <summary>
        /// The speed with which the object moves
        /// </summary>
        public float MovingSpeed
        {
            get { return _movingSpeed; }
            set { _movingSpeed = value; }
        }

        /// <summary>
        /// Determines if the sprite is drawn
        /// </summary>
        public bool Visible
        {
            get { return _visible; }
            set { _visible = value; }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Bounding box for collisions
        /// </summary>
        // TODO: Needs to be recreated if the model rotates
        public Rectangle GetBoundingBox()
        {
            return new Rectangle((int)Position.X, (int)Position.Y, Width, Height);
        }

        /// <summary>
        /// Updates the sprite
        /// </summary>
        public virtual void Update(GameTime gameTime)
        {
            Position += _velocity * MovingSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
        }

        /// <summary>
        /// Draws the entity on the screen
        /// </summary>
        /// <param name="spriteBatch"></param>
        public abstract void Draw(SpriteBatch spriteBatch);

        /// <summary>
        /// Returns true if the position equals the destination
        /// </summary>
        /// <returns></returns>
        public bool AtDestination()
        {
            if (Vector2.Distance(Position, Destination) < 5f)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion
    }
}